/**
 * JAVACC DEMO 1.0
 * @Package com.apache.portal.servlet.trans
 */
package com.apache.portal.contorller.trans;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.apache.exception.BusinessException;
import com.apache.portal.thread.FileOperateUtil;
import net.sf.json.JSONObject;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.IOUtils;

import com.apache.api.vo.ResultEntity;
import com.apache.api.vo.ResultMsg;
import com.apache.cache.util.Validator;
import com.apache.portal.common.PortalPlugin;
import com.apache.portal.common.annotion.BeanFactory;
import com.apache.portal.common.connector.impl.AdapterFactory;
import com.apache.portal.common.restfull.RequestMapping;
import com.apache.portal.common.restfull.ResultFullAnntation;
import com.apache.portal.common.restfull.SupperAction;
import com.apache.portal.common.template.BuildProjectFactory;
import com.apache.portal.common.template.FreemarkerHelper;
import com.apache.portal.common.template.TemplateConverter;
import com.apache.portal.common.util.FileOperate;
import com.apache.portal.common.util.PortalPubFactory;
import com.apache.tools.StrUtil;
import com.apache.uct.common.LoginUser;
import com.apache.uct.common.ToolsUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * description:  平台模板管理
 * @author qihan 创建时间：2017-6-28  
 */
@SuppressWarnings("serial")
@ResultFullAnntation(name = "transTemplateAction", urlPatterns = { "/trans/template/*" })
public class TransTemplateAction extends SupperAction {
	protected Logger log = LoggerFactory.getLogger(getClass());
	private PortalPlugin netPlugin;
	private String fileRootPath = "";
	// 上传配置
	private static final int MEMORY_THRESHOLD = 1024 * 1024 * 3; // 3MB

	public void init() {
		netPlugin = (PortalPlugin) BeanFactory.getInstance().getBeans("net");
		//fileRootPath = Validator.getClassLoaderPath().replaceAll("classes/", "") + "template/coding/pages/www/";
		fileRootPath = ToolsUtil.getInstance().getLocalByKey("config.properties","html_path") + "/template/";
	}

	protected void doInvoke(HttpServletRequest request, HttpServletResponse response, String methodType)
			throws Exception {
		Method method = doInvoke(this.getClass(), request, response, methodType, "");
		if (null != method) {
			log.info("start doInvoke ["+method.getName()+"] ["+methodType+"].....");
//			boolean flag = checkToken(request, method);
//			if (!flag) {
//				log.info("token验证结果=" + flag);
//				return;
//			}
			Object obj = method.invoke(this, request, response);
			if (!ToolsUtil.isEmpty(obj)) {
				JSONObject array = JSONObject.fromObject(obj);
				this.outputJson(array.toString(), response, request.getParameter("callback"));
			}
		} else {
			gotoErrorPage(request, response, "请求的Action地址未定义");
		}
	}

	/**
	 * description:  保存模板信息带上传
	 */
	@RequestMapping(value = "saveTemp", method = "post")
	public ResultMsg saveTemp(HttpServletRequest request, HttpServletResponse response) throws IOException {
		Map<String, String> params = getParameterMap(request);
		String msg = uploadTemplate(request, params);
		if (StrUtil.isNotNull(msg)) {
			return new ResultMsg("F", msg);
		}
		LoginUser loginUser = PortalPubFactory.getInstance().getLoginUser(request);
		params.put("doCode", "dymicSql");
		params.put("resultType", "processSql");
		//		if (!"webiste".equalsIgnoreCase(params.get("sysTemplate.templateSpace"))) {
		//			params.remove("pageName");
		//			params.remove("formName");
		//		}
		Map<String, Object> result = new HashMap<String, Object>();
		params.put("loginUser_userEname", loginUser.getUserEname());//确保其他表中没有该字段
		params = AdapterFactory.getInstance().getReqParamForBefor("setReqParam,createInfo", params, request, response);//前拦截
		String execptionMsg = String.valueOf(params.get("execptionMsg"));
		if (StrUtil.isNotNull(execptionMsg)) {
			return new ResultMsg("F", execptionMsg);
		}
		ResultEntity entity = (ResultEntity) netPlugin.doInvoke(request, response, params);
		result.put("flag", String.valueOf(entity.getResult()));
		result.put("msg", String.valueOf(entity.getMessage()));
		result.put("ids", entity.getEntity());
		return new ResultMsg(String.valueOf(entity.getResult()), String.valueOf(entity.getMessage()));
	}

	/**
	 * description:  生成页面
	 */
	@RequestMapping(value = "createPage", method = "post")
	public ResultMsg createPage(HttpServletRequest request, HttpServletResponse response) throws IOException {
		/* tempate: codeUrl:生成地址；projectName:工程名;mainObj:主体对象;pageName:页面名称；templateUrl:模板地址；templateName:模板名称:titleName:模块标题名称
		 * 
		 * mainObj:主表的表名称;primaryKeyId:主键名称;portName:pageName;formSearch:查询formName;*/
		/* detail: objName:实体名（操作几张表）；tabNo:tab数量;mainObj:主体对象;tabName:页签名称
		 * 
		 * tabContent:表单内容; formAdd:添加formName;formEdit:修改formName;formDel:删除formName */
		String tempId = request.getParameter("templateId");
		String codeUrl = request.getParameter("codeUrl");
		String pageName = request.getParameter("pageName");
		String mainObj = request.getParameter("mainObj");
		String primaryKeyId = request.getParameter("primaryKeyId");

		if (StrUtil.isNull(tempId)) {
			return new ResultMsg("F", "缺少方法参数");
		}

		return null;
	}

	/**
	 * description:  
	 */
	@RequestMapping(value = "editTemp", method = "post")
	public Object editTemp(HttpServletRequest request, HttpServletResponse response) throws IOException {
		String exeType = request.getParameter("exeType");
		if ("saveTemp".equalsIgnoreCase(exeType)) {//保存模板内容
			ResultMsg msg = new ResultMsg("T", "保存成功");
			Map<String, String> params = this.getParameterMap(request);
			boolean mark = FileOperate.getInstance().newCreateFile(fileRootPath + params.get("fileName"),
					params.get("fileText"));
			if (!mark) {
				msg = new ResultMsg("F", "保存失败");
			}
			return msg;
		} else {//修改模板内容
			Map<String, Object> data = new HashMap<String, Object>();
			String fileName = request.getParameter("fileName");
			String filePath = fileRootPath + fileName;
			File file = new File(filePath);
			if (file.isFile()) {
				InputStreamReader read = new InputStreamReader(new FileInputStream(file), "UTF-8");//考虑到编码格式
				data.put("content", IOUtils.toString(read));
				read.close();
			}
			data.put("fileName", fileName);
			return data;
		}
	}

	/**
	 * description:  预览页面
	 * @throws ServletException 
	 */
	@RequestMapping(value = "previewPage", method = "get")
	public ResultMsg previewPage(HttpServletRequest request, HttpServletResponse response) throws IOException,
			ServletException {
		String tempId = request.getParameter("templateId");
		if (StrUtil.isNull(tempId)) {
			return new ResultMsg("F", "缺少方法参数");
		}
		String path = Validator.getClassLoaderPath().replaceAll("WEB-INF/classes/", "") + "temp/";
		Map<String, Object> map = new HashMap<String, Object>();
		Map<String, Object> paramVo = new HashMap<String, Object>();
		paramVo.put("sysTemplate.w_templateId", tempId);
		paramVo.put("modelTypes", "s_sysTemplate");
		List<Map> list = (List) BuildProjectFactory.instance().init(paramVo);
		if (ToolsUtil.isEmpty(list)) {
			return new ResultMsg("F", "没有获取到定义的模板");
		}
		Map temp = list.get(0);
		map.put("template", temp);
		String projectName = String.valueOf(temp.get("projectName"));//工程名
		Map<String, Object> data = new HashMap<String, Object>();
		String infoTableName = String.valueOf(temp.get("mainObj"));//主体对象 ,如：trpTest  
		List<Map> sortInfoList = null;
		if (StrUtil.isNotNull(infoTableName)) {
		} else {
			temp.put("main_obj", "");
			temp.put("main_id", "");
		}
		if (StrUtil.isNull(String.valueOf(temp.get("titleName")))) {
			temp.put("title_name", "");
		}
		if (StrUtil.isNull(String.valueOf(temp.get("portName")))) {
			temp.put("port_name", "");
		}
		if (StrUtil.isNull(String.valueOf(temp.get("formSearch")))) {
			temp.put("form_search", "");
			temp.put("form_del", "");
		}
		if (StrUtil.isNull(String.valueOf(temp.get("ifSingle")))) {
			temp.put("if_single", "F");
		}
		if (StrUtil.isNull(String.valueOf(temp.get("menuId")))) {
			temp.put("menu_id", "");
		}

		String sortCode = "";
		String objName = "";
		String primaryKeyId = "";
		String dataPrimaryKey = "";
		if (null != sortInfoList) {
		} else {
			data.put("sort", null);
			data.put("objName", StrUtil.doNull(objName, String.valueOf(temp.get("mainObj"))));
			data.put("primaryKeyId", StrUtil.doNull(primaryKeyId, String.valueOf(temp.get("mainId"))));
			data.put("dataPrimaryKey", dataPrimaryKey);
		}
		data.put("detailList", new ArrayList());
		try {
			String path2 = Validator.getClassLoaderPath().replaceAll("classes/", "") + "/pages/" + projectName;
			if (FileOperate.getInstance().checkFolder(path2)) {
			} else {
				projectName = "plateform";
			}
			data.put("projectName", projectName);
			data.put("metadataList", new HashMap<String, Object>());
			data.put("objNameMap", new HashMap<String, Object>());
			data.put("objNameAllMap", new HashMap<String, Object>());
			String templateDefaultName = String.valueOf(temp.get("templateUrl")) + "/"
					+ String.valueOf(temp.get("templateName"));
			data.put("template", temp);
			FileOperate.getInstance().newCreateFolder(path);//生成路径
			String result = FreemarkerHelper.instance().getTemplateStr(data, templateDefaultName);
			result = result.replace("###", "$");
			result = result.replace("<%@include file=\"/common/" + projectName + "/left.jsp\" %>", "");
			FileOperate.getInstance().newCreateFile(path + "temp.jsp", result);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("预览页面失败", e);
		}
		request.getRequestDispatcher("/temp/temp.jsp").forward(request, response);
		return null;
	}

	private String uploadTemplate(HttpServletRequest request, Map<String, String> params) {
		// 配置上传参数
		DiskFileItemFactory factory = new DiskFileItemFactory();
		// 设置内存临界值 - 超过后将产生临时文件并存储于临时目录中
		factory.setSizeThreshold(MEMORY_THRESHOLD);
		// 设置临时存储目录
		factory.setRepository(new File(System.getProperty("java.io.tmpdir")));
		ServletFileUpload upload = new ServletFileUpload(factory);
		// 设置最大文件上传值
		upload.setFileSizeMax(MEMORY_THRESHOLD);
		// 中文处理
		upload.setHeaderEncoding("UTF-8");
		try {
			// 解析请求的内容提取文件数据
			@SuppressWarnings("unchecked")
			List<FileItem> formItems = upload.parseRequest(request);
			if (formItems != null && formItems.size() > 0) {
				// 迭代表单数据
				int k = 0;
				for (int i = 0; i < formItems.size(); i++) {
					FileItem item = formItems.get(i);
					if (!item.isFormField()) {
						k = i;
					} else {
						String value = IOUtils.toString(item.getInputStream(), "UTF-8");
						String ok = item.getFieldName();
						if (StrUtil.isNotNull(value)) {
							String str = new String(value.getBytes("iso8859-1"), "iso8859-1");
							if (value.equals(str)) {
								value = str;
							}
							params.put(ok, value);
						} else {
							if (ok.indexOf("s_") != -1) {
								params.put(ok, "is null");//清空
							}
						}
					}
				}
				String filePath = fileRootPath + params.get("sysTemplate.templateUrl");
				if (!FileOperate.getInstance().checkFolder(filePath)) {
					FileOperate.getInstance().newCreateFolder(filePath);
				}
				FileItem item = formItems.get(k);
				if (!item.isFormField()) {
					//String fileName = new File(item.getName()).getName();
					String file = filePath + File.separator + params.get("sysTemplate.templateName");
					File storeFile = new File(file);
					// 保存文件到硬盘
					item.write(storeFile);
				}
			}
			return "";
		} catch (Exception ex) {
			ex.printStackTrace();
			return "错误信息: " + ex.getMessage();
		}
	}

	/**
	 * description:  复制模板文件
	 */
	@RequestMapping(value = "copyTemp", method = "post")
	public ResultMsg copyTemp(HttpServletRequest request, HttpServletResponse response) throws IOException {
		Map<String, String> params = getParameterMap(request);
		//		String ctxRoot = request.getSession().getServletContext().getRealPath("/");//tomcat web root新工程目录
		String ctxRoot = ToolsUtil.getInstance().getLocalByKey("config.properties","html_path") + "/";//配置目录
		log.info("ctxRoot->"+ctxRoot);
		//		String sysTempRoot = ToolsUtil.getInstance().getValueByKey("menu_path") + "/";
		//		sysTempRoot+="WEB-INF/template/";
		//		sysTempRoot= ctxRoot;
		String sysTempPath = ctxRoot + "template" + params.get("tempPath");//系统模板路径
		log.info("sysTempPath->"+sysTempPath);

		String siteCode = params.get("siteCode");
		File oldfile = new File(sysTempPath);

		String templateRoot = ctxRoot + siteCode + "/template/";
		if(!FileOperate.getInstance().checkFolder(templateRoot)){
			FileOperate.getInstance().newCreateFolder(templateRoot);//创建站点下 template 文件夹
		}
		String targetPath = templateRoot + oldfile.getName();//站点目标模板路径
		log.info("targetPath->"+targetPath);
		File targetfile = new File(targetPath);

		boolean flag = false;
		ResultMsg msg = new ResultMsg("F", "文件拷贝操作失败！");
		try {
			if (oldfile.exists()) {
                //把oldfile文件拷贝到targetfile中
                flag = copy(oldfile, targetfile);
            }
		} catch (IOException e) {
			e.printStackTrace();
		}
		String newFileP = oldfile.getName();
		if (flag) {
			msg = new ResultMsg("T", newFileP);
		}
		return msg;
	}

	/**
	 * description:  复制模板目录文件
	 */
	@RequestMapping(value = "copyDir", method = "post")
	public ResultMsg copyDir(HttpServletRequest request, HttpServletResponse response) throws IOException {
		Map<String, String> params = getParameterMap(request);
		String ctxRoot = ToolsUtil.getInstance().getLocalByKey("config.properties","html_path") + "/";//配置目录
		String siteCode = params.get("siteCode");
		String tempDir = params.get("tempDir");
		String [] tempDirArray = new String[]{"common","images"};
//		for (String dir:tempDirArray){
			String sourcePath = ctxRoot+"template/"+tempDir;
			String targetSiteRoot = ctxRoot + siteCode;
			log.info("开始复制文件目录："+sourcePath+" -> "+targetSiteRoot);
			FileOperate.getInstance().copyDir(sourcePath,targetSiteRoot);
//		}
		ResultMsg msg = new ResultMsg("T", "文件拷贝操作完成！");
		return msg;
	}

	/**
	 * description:  保存敏感字
	 */
	@RequestMapping(value = "saveKeyWord", method = "post")
	public ResultMsg saveKeyWord(HttpServletRequest request, HttpServletResponse response) throws IOException {
		ResultMsg msg = new ResultMsg("T", "保存成功");
		String content = request.getParameter("keyWords");
		String filePath = ToolsUtil.getClassLoaderPath() + "config/keyword.properties";
		FileOperate.getInstance().newCreateFile(filePath, content);
		return msg;
	}

	/**
	 * description:  保存敏感字
	 */
	@RequestMapping(value = "viewKeyWord", method = "get")
	public Object viewKeyWord(HttpServletRequest request, HttpServletResponse response) throws IOException {
		String path = ToolsUtil.getClassLoaderPath() + "config/keyword.properties";
		InputStream in = new BufferedInputStream(new FileInputStream(path));
		String content = IOUtils.toString(in, "UTF-8");
		Map<String, String> data = new HashMap<String, String>();
		data.put("content", content);
		return data;
	}

	/**
	 * description: 替换模板内容
	 */
	@RequestMapping(value = "setTemplateParams")
	public Object setTemplateParams(HttpServletRequest request, HttpServletResponse response) throws Exception {
		Map<String, String> data = new HashMap<String, String>();
		String filePath = request.getParameter("filePath");
		String tempCode = request.getParameter("code");
		String newContent = request.getParameter("newContent");
		String str = new String(newContent.getBytes("iso8859-1"), "iso8859-1");
		if (newContent.equals(str)) {
			newContent = str;
		}
		Map<String, String> param = new HashMap<String, String>();
		param.put("incFileName", filePath);//路径加模板名
		param.put("converContent", newContent);//要替换的内容
		param.put("tempId", tempCode);//替换段代码

		//后台使用
		String flagType = request.getParameter("flagType");//操作类型
		if (StrUtil.isNotNull(flagType)) {
			param.put("flagType", "admin");//操作类型
		}

		TemplateConverter tc = new TemplateConverter();
		String content = String.valueOf(tc.execute(param));
		data.put("flag", content);
		data.put("msg", "操作成功");
		return data;
	}

	/**
	 * description:  外部数据静态化json
     *
	 */
	@RequestMapping(value = "convertData", method = "post")
	public ResultMsg convertData(HttpServletRequest request, HttpServletResponse response) throws IOException {
		try {
			String path = ToolsUtil.getInstance().getLocalByKey("config.properties","html_path") + "/";;
			path = path.replaceAll("/wcm", "");
			String folderPath = Validator.getDefaultStr(String.valueOf(request.getParameter("folderPath")), path);
			String channelCode = String.valueOf(request.getParameter("fileName"));
			String dataUrl = String.valueOf(request.getParameter("dataUrl"));
			if (Validator.isNotNull(channelCode) && Validator.isNotNull(dataUrl)) {
				URL url = new URL(dataUrl);
				HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
				urlConnection.setRequestMethod("GET");
				urlConnection.connect();
				InputStream inputStream = urlConnection.getInputStream();
				String responseStr = IOUtils.toString(inputStream, "UTF-8");
				System.out.println(responseStr);
				String fileName = path + folderPath + "/" + channelCode + ".json";
				FileOperateUtil.newCreateFolder(path + folderPath);
				boolean returnFalg = FileOperateUtil.newCreateFile(fileName, responseStr, "UTF-8");
				this.log.info("数据文件生成：" + fileName + "   |   " + returnFalg);
			}

			return new ResultMsg("T","数据静态化成功！");
		} catch (Exception var12) {
			throw new BusinessException("数据静态化失败：" + var12.getMessage());
		}

	}

	//读取文件内容
	@RequestMapping(value = "doFile", method = "post")
	protected Object doFile(HttpServletRequest request, HttpServletResponse response)
			throws IOException {
		String root = Validator.getDefaultStr(request.getParameter("fileRoot"),
				ToolsUtil.getInstance().getLocalByKey("config.properties", "temp_path"));
		String id = request.getParameter("id") + "/" + request.getParameter("fileName");
		String filePath = FileOperate.getInstance().formatFilePath(root);
		if (ToolsUtil.isNotNull(id)) {
			filePath += id;
		}
		File file = new File(filePath);
		StringBuffer sb = new StringBuffer();
		Map<String, Object> resultMap = new HashMap<String, Object>();
		if (file.isFile()) {
			InputStreamReader read = new InputStreamReader(new FileInputStream(file),
					"UTF-8");//考虑到编码格式
			sb.append(IOUtils.toString(read));
			read.close();
			resultMap.put("flag", "T");
			resultMap.put("msg", "读取成功");
		} else {
			resultMap.put("flag", "F");
			resultMap.put("msg", "未找到文件，请检查对应目录下此文件是否存在！");
		}

		resultMap.put("content", sb.toString());
		resultMap.put("fileName", id);
		return resultMap;
	}
	//保存文件
	@RequestMapping(value = "saveFile", method = "post")
	protected ResultMsg saveFile(HttpServletRequest request, HttpServletResponse response) throws IOException {
		ResultMsg msg = new ResultMsg("T", "保存成功");
		String root = Validator.getDefaultStr(request.getParameter("fileRoot"),
				ToolsUtil.getInstance().getLocalByKey("config.properties", "temp_path"));
		Map<String, String> params = this.getParameterMap(request);

		String filePath = FileOperate.getInstance().formatFilePath(root);

		boolean mark = FileOperate.getInstance()
				.newCreateFile(filePath + params.get("fileName"), params.get("fileText"));

		log.info("filePath >>> " + filePath + params.get("fileName") + " edit is " + mark);

		if (!mark) {
			msg = new ResultMsg("F", "保存失败");
		}
		return msg;
	}
	@RequestMapping(value = "fileList", method = "get")
	protected Object fileList(HttpServletRequest request, HttpServletResponse response)
			throws IOException {
		String root = Validator.getDefaultStr(request.getParameter("fileRoot"),
				ToolsUtil.getInstance().getLocalByKey("config.properties", "temp_path"));
		String floderName = FileOperate.getInstance()
				.formatFilePath(request.getParameter("floderName"));
		Map<String, Object> resultMap = new HashMap<String, Object>();
		String filePath = FileOperate.getInstance().formatFilePath(root);
		String parentId = "0";
		if (ToolsUtil.isNotNull(floderName)) {
			filePath += floderName.replace("-", "/");
			parentId = floderName.replace("/", "-");
		}
		log.info("读取指定目录下文件；"+filePath);
		File[] files = FileOperate.getInstance().getFileList(filePath);
		List<Map<String, String>> list = new ArrayList<Map<String, String>>();
		if (null != files && files.length > 0) {
			//			if (!ToolsUtil.isNull(floderName)) {
			//				Map<String, String> upFloder = new HashMap<String, String>();
			//				upFloder.put("id", floderName);
			//				upFloder.put("isfloder", "T");
			//				upFloder.put("parentId", parentId);
			//				upFloder.put("text", floderName.substring(floderName.lastIndexOf("/") + 1));
			//				list.add(upFloder);
			//			}
			String filters = ToolsUtil.getInstance()
					.getLocalByKey("config.properties", "filter_temp");
			for (int i = 0; i < files.length; i++) {
				File file = files[i];
				if (file.isDirectory()) {
					if (filters.indexOf(file.getName()) != -1) {
						log.info("过滤目录；"+file.getName());
						continue;
					}
				}else{
					String fileName = file.getName();
					String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
					if(filters.indexOf(suffix.toLowerCase())>-1){
						log.info("过滤文件；"+fileName);
						continue;
					}
				}
				Map<String, String> map = new HashMap<String, String>();
				String path = FileOperate.getInstance().formatFilePath(file.getPath());
				map.put("floder", floderName.replace("-", "/"));
				map.put("id", path.replace(FileOperate.getInstance().formatFilePath(root), "")
						.replace("/", "-"));
				map.put("isfloder", file.isDirectory() ? "T" : "F");
				map.put("parentId", parentId);
				map.put("text", file.getName());
				list.add(map);
			}
			resultMap.put("total", list.size());
			resultMap.put("rows", list);
		}
		return resultMap;
	}

	private boolean copy(File file, File target) throws IOException {
		if (file.isDirectory()) {
			return false;
		}
		FileInputStream fi = null;
		FileOutputStream fo = null;
		try {
			fi = new FileInputStream(file);
			fo = new FileOutputStream(target);
			byte buff[] = new byte[1024];
			for (int n = 0; (n = fi.read(buff)) != -1;) {
				fo.write(buff, 0, n);
			}
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		} finally {
			if (fo != null)
				fo.close();
			if (fi != null)
				fi.close();
		}
	}
}
